package stock

import (
	"errors"
	// "fmt"
	"sync"
	"time"
	// "time"
)

type Stock struct {
	stock int
	mu    sync.Mutex
}

func (s *Stock) Decrease(d int, useLock bool) (err error) {
	if useLock {
		s.mu.Lock()
		defer s.mu.Unlock()
	}

	temp := s.stock
	// fmt.Printf("拿到的库存：%d \n", temp)
	// 为什么判断了库存小于等于0时扣减库存，库存永远不会为负库存，按我的思考：
	//其实虽说是并发，单其实还是并不均匀的并发，启动协程的时候第一个请求肯定是先到的，它把库存扣减后变成0了。后面的请求再怎么请求都不会被扣减。
	//而且现实情况下库存是放在数据库中的而不是程序内存中的，放在程序内存中不能很好的模拟多线程竞争时的情况的。
	//当并发时多个线程都拿到了库存为1，还是有库存的。然后用这个库存执行扣减。其他线程实际上已经扣减为0了，然后你再拿着库存进行扣减。哦豁，负库存或者扣减失败了。
	// 实际上拿到同样库存数量的几个请求已经出现库存问题了，库存已经超卖了。
	if temp <= 0 {
		return errors.New("stock is zero.")
	}
	// 执行其他业务逻辑的延迟 3毫秒
	time.Sleep(time.Millisecond * 3)
	s.stock = temp - d
	return
}

func (s *Stock) Save(stock int) {
	s.stock = stock
}

func (s *Stock) Get() int {
	return s.stock
}

func NewStock(stock int) (s *Stock) {
	s = &Stock{
		stock: stock,
		mu:    sync.Mutex{},
	}
	return
}
